#include <my_header.h>
// 代码一: 线程A先获得锁一再获得锁二, 线程B先获得锁二再获
// 得锁一; 这是一个死锁逻辑
// 使用trylock可解锁此死锁问题
//  运行逻辑：首先先将两把锁(mLock1.mLock2)给主线程，主线程
//  用1s之后给子线程. 子线程需要睡1s不然启动不了,可能是因为
//  锁的抢占问题，此时子线程先获得锁2，再次获得锁1奖阻塞，
//  trylock发挥了作用。阻塞
/* Usage: ./16_trylock */
typedef struct share_value{
    int num;
    pthread_mutex_t mLock1;
    pthread_mutex_t mLock2;
}ShareValue;
// 子线程
void *threadFunc(void *arg)
{
    // 声明一个对象 并将形参传入
    ShareValue *pshareValue = (ShareValue *)arg;
    sleep(1);
    while(1)
    {   // // 通过while循环 (这其实是自旋锁机制), 反复
// 的试图获取所有锁, 获取不到所有的锁, 则不持有任何锁
        // 首先加锁2
        pthread_mutex_lock(&pshareValue->mLock2);
        sleep(1);
        // trylock锁1 可能已被主线程持有
        int res_trylock = pthread_mutex_trylock(&pshareValue->mLock1);
        if(res_trylock !=0 )
        {
            pthread_mutex_unlock(&pshareValue->mLock2);
            continue;
        }
        printf("child thread running...\n");

        // 解锁
        pthread_mutex_unlock(&pshareValue->mLock1);
        pthread_mutex_unlock(&pshareValue->mLock2);
        break;
    }
    return NULL;
}
int main(void){                                  
    // 初始化数据结构体
    ShareValue shareVlue;
    shareVlue.num = 0;

    // 初始化锁
    pthread_mutex_init(&shareVlue.mLock1,NULL);
    pthread_mutex_init(&shareVlue.mLock2,NULL);

    pthread_t tid;
    // 传参一级指针
    int ret = pthread_create(&tid, NULL, threadFunc, &shareVlue);
    THREAD_ERROR_CHECK(ret, "pthread_create");

    // 加两把锁
    pthread_mutex_lock(&shareVlue.mLock1);
    sleep(1);
    pthread_mutex_lock(&shareVlue.mLock2);
    printf("main thread running ... \n");

    // 解锁
    pthread_mutex_unlock(&shareVlue.mLock2);
    pthread_mutex_unlock(&shareVlue.mLock1);

    // 捕获tid 等待线程并回收资源
    pthread_join(tid,NULL);
    // 销毁锁
    pthread_mutex_destroy(&shareVlue.mLock1);
    pthread_mutex_destroy(&shareVlue.mLock2);


    return 0;
}


